# -*- mode: makefile -*-
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
#

#
# Copyright (c) 2014, Joyent, Inc.
#

#
# Makefile.node_prebuilt.defs: Makefile for including a prebuilt Node.js build.
#
# NOTE: This makefile comes from the "eng" repo. It's designed to be dropped
# into other repos as-is without requiring any modifications. If you find
# yourself changing this file, you should instead update the original copy in
# eng.git and then update your repo to use the new version.
#

#
# This Makefile facilitates downloading and bundling a prebuilt node.js
# build (using the 'sdcnode' distro builds). This is an alternative to
# the "Makefile.node.*" makefiles for *building* a node from source.
#
# Usage:
#
# - Define `NODE_PREBUILT_VERSION` in your Makefile to choose a node version.
#   E.g.: `NODE_PREBUILT_VERSION=v0.6.19`. See other optional variables
#   below.
# - `include tools/mk/Makefile.node_prebuilt.defs` after this in your Makefile.
# - `include tools/mk/Makefile.node_prebuilt.targ` near the end of your
#   Makefile.
# - Have at least one of your Makefile targets depend on either `$(NODE_EXEC)`
#   or `$(NPM_EXEC)`. E.g.:
#
#		node_modules/restify: deps/restify $(NPM_EXEC)
#			$(NPM) install deps/restify
#
#   or better, use an order-only dependency to avoid spurious rebuilds:
#
#		node_modules/restify: deps/restify | $(NPM_EXEC)
#			$(NPM) install deps/restify
#
# - Use `$(NPM)` or `$(NODE)` to use your node build.
# - Include the "$(NODE_INSTALL)" tree in your release package.
#
#
# When including this Makefile, you MUST also specify:
#
#	NODE_PREBUILT_VERSION 	The node version in the prebuilt 'sdcnode'
#				package to use. Typically this is one of the
#				node version tags, e.g. "v0.6.18" but it
#				can be any commitish.
#
# When including this Makefile, you MAY also specify:
#
#	NODE_PREBUILT_DIR 	The dir in which to find sdcnode builds. This
#				can either be a *local directory* or *a
#				URL* dir (with trailing '/') which serves
#				Apache/Nginx dir listing HTML.
#				(default: sdcnode master build dir on stuff)
#
#	NODE_PREBUILT_TAG	The 'sdcnode' project supports special
#				configuration builds of node, e.g. say a
#				build configured `--without-ssl`. These
#				special configurations are given a tag, e.g.
#				'gz', that is used in the filename. Optionally
#				specify a tag name here.
#				(default: empty)
#
#	NODE_PREBUILT_BRANCH	Specify a particular branch of 'sdcnode' builds
#				from which to pull. Generally one should stick
#				with the default.
#				(default: master)
#
#	NODE_PREBUILT_IMAGE		If you have a zone image that differs from that
#				for an sdcnode build that you want to use (potential compat
#				issues be damned), then set this to the UUID of the sdcnode
#				build you want. See here for available build image uuids:
#				<https://download.joyent.com/pub/build/sdcnode/master-latest/sdcnode/>
#
#	BUILD			top-level directory for built binaries
#				(default: "build")
#
#	NODE_INSTALL		where node should install its built items
#				(default: "$BUILD/node")
#
#
# Dev Notes:
#
# This works by getting "NODE_PREBUILT_NAME" from the provided "NODE_PREBUILT_*"
# vars and the image version (via 'mdata-get sdc:image_uuid'). The image uuid is
# included to ensure an exact match with the build machine. This name (e.g.
# "v0.6.18-zone-$uuid") is used to find a matching "sdcnode-$name-*.tgz" build
# in "NODE_PREBUILT_DIR" (either a local directory or a URL). That tarball is
# downloaded and extracted into "NODE_INSTALL".
#
# The "*_EXEC" vars are set to named symlinks, e.g.
# "build/prebuilt-node-v0.6.18-$uuid", so that a change of selected node
# build (say the developer changes NODE_PREBUILT_VERSION) will recreate the
# node install.
#
# See <https://mo.joyent.com/docs/sdcnode/master/> for details on 'sdcnode-*'
# package naming.
#

TOP ?= $(error You must include Makefile.defs before this makefile)
NODE_PREBUILT_VERSION ?= $(error NODE_PREBUILT_VERSION is not set.)


BUILD		?= build
NODE_INSTALL	?= $(BUILD)/node
DISTCLEAN_FILES	+= $(NODE_INSTALL) \
	$(BUILD)/prebuilt-node-* $(BUILD)/prebuilt-npm-*

NODE_PREBUILT_BRANCH ?= master
NODE_PREBUILT_IMAGE ?= $(shell pfexec mdata-get sdc:image_uuid)
ifeq ($(NODE_PREBUILT_TAG),)
	NODE_PREBUILT_NAME := $(NODE_PREBUILT_VERSION)-$(NODE_PREBUILT_IMAGE)
else
	NODE_PREBUILT_NAME := $(NODE_PREBUILT_VERSION)-$(NODE_PREBUILT_TAG)-$(NODE_PREBUILT_IMAGE)
endif
NODE_PREBUILT_PATTERN := sdcnode-$(NODE_PREBUILT_NAME)-$(NODE_PREBUILT_BRANCH)-.*\.tgz
NODE_PREBUILT_DIR ?= https://download.joyent.com/pub/build/sdcnode/$(NODE_PREBUILT_IMAGE)/$(NODE_PREBUILT_BRANCH)-latest/sdcnode/
ifeq ($(shell echo $(NODE_PREBUILT_DIR) | cut -c 1-4),http)
	NODE_PREBUILT_BASE := $(shell curl -ksS --fail --connect-timeout 30 $(NODE_PREBUILT_DIR) | grep 'href=' | cut -d'"' -f2 | grep "^$(NODE_PREBUILT_PATTERN)$$" | sort | tail -1)
	ifneq ($(NODE_PREBUILT_BASE),)
		NODE_PREBUILT_TARBALL := $(NODE_PREBUILT_DIR)$(NODE_PREBUILT_BASE)
	endif
else
	NODE_PREBUILT_BASE := $(shell ls -1 $(NODE_PREBUILT_DIR)/ | grep "^$(NODE_PREBUILT_PATTERN)$$" 2>/dev/null | sort | tail -1)
	ifneq ($(NODE_PREBUILT_BASE),)
		NODE_PREBUILT_TARBALL := $(NODE_PREBUILT_DIR)/$(NODE_PREBUILT_BASE)
	endif
endif
ifeq ($(NODE_PREBUILT_TARBALL),)
	NODE_PREBUILT_TARBALL = $(error NODE_PREBUILT_TARBALL is empty: no '$(NODE_PREBUILT_DIR)/$(NODE_PREBUILT_PATTERN)' found)
endif


# Prebuild-specific paths for the "*_EXEC" vars to ensure that
# a prebuild change (e.g. if master Makefile's NODE_PREBUILT_VERSION
# choice changes) causes a install of the new node.
NODE_EXEC	:= $(BUILD)/prebuilt-node-$(NODE_PREBUILT_NAME)
NODE_WAF_EXEC	:= $(BUILD)/prebuilt-node-waf-$(NODE_PREBUILT_NAME)
NPM_EXEC	:= $(BUILD)/prebuilt-npm-$(NODE_PREBUILT_NAME)

# Ensure these use absolute paths to the executables to allow running
# from a dir other than the project top.
NODE		:= $(TOP)/$(NODE_INSTALL)/bin/node
NODE_WAF	:= $(TOP)/$(NODE_INSTALL)/bin/node-waf
NPM		:= PATH=$(TOP)/$(NODE_INSTALL)/bin:$(PATH) node $(TOP)/$(NODE_INSTALL)/bin/npm
